package com.example.delicioushunter.view.activity;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import com.example.delicioushunter.R;
import com.example.delicioushunter.control.databasecontrol.MaterialControl;
import com.example.delicioushunter.control.supportcontrol.BitmapProcess;
import com.example.delicioushunter.control.supportcontrol.CameraProcess;
import com.example.delicioushunter.control.supportcontrol.DHSharedPreference;
import com.example.delicioushunter.model.database.DHDatabaseHelper;
import com.example.delicioushunter.model.object.Material;
import com.example.delicioushunter.view.adapter.MaterialGalleryAdapter;
import com.samsung.android.sdk.pen.document.SpenNoteDoc;
import com.samsung.android.sdk.pen.document.SpenObjectBase;
import com.samsung.android.sdk.pen.document.SpenObjectImage;
import com.samsung.android.sdk.pen.document.SpenObjectStroke;
import com.samsung.android.sdk.pen.document.SpenObjectTextBox;
import com.samsung.android.sdk.pen.document.SpenPageDoc;
import com.samsung.android.sdk.pen.document.SpenPageDoc.ObjectListener;
import com.samsung.android.sdk.pen.engine.SpenContextMenuItemInfo;
import com.samsung.android.sdk.pen.engine.SpenControlBase;
import com.samsung.android.sdk.pen.engine.SpenControlListener;
import com.samsung.android.sdk.pen.engine.SpenSurfaceView;
import com.samsung.android.sdk.pen.engine.SpenTouchListener;

import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.Log;
import android.view.Display;
import android.view.Menu;
import android.view.MotionEvent;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.FrameLayout;
import android.widget.Gallery;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;
import android.view.View;
import android.view.View.OnTouchListener;

@SuppressWarnings("deprecation")
public class AddMaterialActivity extends Activity {

	private static final int CONTEXT_MENU_GALLERY = 1;
	private static final int CONTEXT_MENU_CAMERA = 2;
	private static final int REQUEST_CODE_IMAGE_GALLERY = 3;
	private static final int REQUEST_CODE_CAMERA_CAPTURE = 4;
	private static final int REQUEST_CODE_CROP = 5;
	protected static final int CONTEXT_MENU_DELETE_ID = 0;

	private final int MODE_PEN = 6;
	private final int MODE_SELECT = 7;
	private final int MODE_TEXT = 8;
	/**
	 * Spen Objects
	 */
	private SpenNoteDoc mSpenNoteDoc;
	private SpenPageDoc mSpenPageDoc;
	private SpenSurfaceView mSpenSurfaceView;
	private SpenObjectImage imgMaterials;
	/**
	 * Views
	 */
	private RelativeLayout spenViewLayout;
	private Gallery galleryMaterials;
	ImageView imgPen, imgText, imgSelect, imgView, imgSave;

	/**
	 * Properties
	 */
	private Rect rect;
	private int mMode = MODE_PEN;
	boolean isSpenFearureEnabled = false;
	private Context mContext;
	private Uri picUri;
	private ArrayList<Bitmap> images;
	private MaterialGalleryAdapter adapter;
	private Bitmap bitmap = null;
	private ArrayList<SpenObjectTextBox> names;
	private ProgressDialog pd;
	private DHSharedPreference shared;
	BitmapProcess process;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		mContext = this;
		setContentView(R.layout.activity_add_material);
		shared = new DHSharedPreference(mContext);
		isSpenFearureEnabled = shared.getIsSpenFeatureEnabled();
		process = new BitmapProcess();
		try {
			buildPage();
			loadView();
		} catch (Exception e) {
			e.printStackTrace();
			finish();
		}
	}

	private void loadView() {
		galleryMaterials = (Gallery) findViewById(R.id.galleryMaterials);
		images = new ArrayList<Bitmap>();

		adapter = new MaterialGalleryAdapter(this, images);
		galleryMaterials.setAdapter(adapter);
		galleryMaterials.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View v,
					int position, long id) {
				images.remove(position);
				adapter.notifyDataSetChanged();
			}
		});

		imgPen = (ImageView) findViewById(R.id.imgPen);
		imgText = (ImageView) findViewById(R.id.imgText);
		imgSelect = (ImageView) findViewById(R.id.imgSelect);
		imgView = (ImageView) findViewById(R.id.imgView);
		imgSave = (ImageView) findViewById(R.id.imgSave);

		imgPen.setOnTouchListener(imgPenTouch);
		imgText.setOnTouchListener(imgTextTouch);
		imgSelect.setOnTouchListener(imgSelectTouch);
		imgView.setOnTouchListener(imgViewTouch);
		imgSave.setOnTouchListener(imgSaveTouch);
	}

	private class BuidDataTask extends AsyncTask<Void, Void, Void> {

		@Override
		protected void onPostExecute(Void result) {
			super.onPostExecute(result);
			pd.dismiss();
		}

		@Override
		protected void onPreExecute() {
			pd = new ProgressDialog(mContext, R.style.MyDialogTheme);
			pd.setMessage("Loading..");
			pd.show();
		}

		@Override
		protected Void doInBackground(Void... params) {
			try {

				if (mSpenSurfaceView == null) {
					Toast.makeText(mContext,
							"Cannot creat new SpenSurfaceView",
							Toast.LENGTH_SHORT).show();
					finish();
				}

				spenViewLayout.addView(mSpenSurfaceView);
				// Get the dimensions of the screen
				Display display = getWindowManager().getDefaultDisplay();
				rect = new Rect();
				display.getRectSize(rect);

				mSpenNoteDoc = new SpenNoteDoc(mContext, 800,
						1050);

				// Create SpenPageDoc
				mSpenPageDoc = mSpenNoteDoc.appendPage();
				loadBackground();
				mSpenPageDoc.clearHistory();

				// Set SpenPageDoc to SpenSurfaceView
				mSpenSurfaceView.setPageDoc(mSpenPageDoc, true);
				mSpenSurfaceView.setControlListener(mControlListener);
				mSpenPageDoc.setObjectListener(mSpenObjectListener);
				mSpenSurfaceView.setTouchListener(mPenTouchListener);

				if (isSpenFearureEnabled == false) {
					mSpenSurfaceView.setToolTypeAction(
							SpenSurfaceView.TOOL_FINGER,
							SpenSurfaceView.ACTION_STROKE);
					Toast.makeText(
							mContext,
							"Device is not support Spen. \n "
									+ "You can draw stroke with your finger",
							Toast.LENGTH_SHORT).show();
				}

				imgMaterials = new SpenObjectImage();
				Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
						R.drawable.ic_collect);
				imgMaterials.setRect(new RectF(100, 270, 700, 900), false);
				imgMaterials.setImage(bitmap);
				imgMaterials.setMovable(false);
				imgMaterials.setRotatable(false);
				imgMaterials.setMaxSize(600, 630);
				imgMaterials.setMinSize(600, 630);
				mSpenPageDoc.appendObject(imgMaterials);
				mSpenSurfaceView.setZoomable(false);
				mSpenSurfaceView.update();
				bitmap.recycle();
				bitmap = null;
			} catch (IOException e) {
				Toast.makeText(mContext, "Cannot create new NoteDoc.",
						Toast.LENGTH_SHORT).show();
				e.printStackTrace();
				finish();

			} catch (Exception e) {
				e.printStackTrace();
				finish();
			}
			return null;
		}
	}

	private void buildPage() {
		spenViewLayout = (RelativeLayout) findViewById(R.id.spenViewLayout);
		mSpenSurfaceView = new SpenSurfaceView(mContext);
		BuidDataTask task = new BuidDataTask();
		task.execute();
	}

	private void loadBackground() {
		String root = this.getExternalCacheDir().getAbsolutePath();
		File myDir = new File(root + "/Delicious Hunter/Background");
		myDir.mkdirs();

		String filePath = myDir.listFiles()[6].getAbsolutePath();
		mSpenPageDoc.setBackgroundImage(filePath);
	}

	private SpenTouchListener mPenTouchListener = new SpenTouchListener() {

		@Override
		public boolean onTouch(View view, MotionEvent event) {
			if (event.getAction() == MotionEvent.ACTION_UP
					&& event.getToolType(0) == SpenSurfaceView.TOOL_SPEN) {
				SpenControlBase control = mSpenSurfaceView.getControl();
				if (control == null) {
					if (mSpenSurfaceView
							.getToolTypeAction(SpenSurfaceView.TOOL_SPEN) == SpenSurfaceView.ACTION_TEXT) {
						SpenObjectTextBox textObj = new SpenObjectTextBox();
						RectF rect = getRealPoint(event.getX(), event.getY(),
								0, 0);
						rect.right += 200;
						rect.bottom += 50;
						textObj.setRect(rect, true);
						mSpenPageDoc.appendObject(textObj);
						mSpenPageDoc.selectObject(textObj);
						mSpenSurfaceView.update();
					}
				}
			}
			return false;
		}
	};

	private RectF getRealPoint(float x, float y, float width, float height) {
		float panX = mSpenSurfaceView.getPan().x;
		float panY = mSpenSurfaceView.getPan().y;
		float zoom = mSpenSurfaceView.getZoomRatio();
		width *= zoom;
		height *= zoom;
		RectF realRect = new RectF();
		realRect.set((x - width / 2) / zoom + panX, (y - height / 2) / zoom
				+ panY, (x + width / 2) / zoom + panX, (y + height / 2) / zoom
				+ panY);
		return realRect;
	}

	private ObjectListener mSpenObjectListener = new ObjectListener() {

		@Override
		public void onObjectRemoved(SpenPageDoc page,
				ArrayList<SpenObjectBase> objectList, int type) {
			// TODO Auto-generated method stub

		}

		@Override
		public void onObjectChanged(SpenPageDoc page,
				SpenObjectBase objectList, int type) {
			// TODO Auto-generated method stub

		}

		@Override
		public void onObjectAdded(SpenPageDoc page,
				ArrayList<SpenObjectBase> objectList, int type) {
			if (objectList.get(0).getType() == SpenObjectStroke.TYPE_STROKE) {
				RectF rect = objectList.get(0).getRect();
				mSpenPageDoc.removeObject(objectList.get(0));
				mSpenSurfaceView.update();
				if (images.size() < 6) {
					if (rect.left > 100 && rect.top > 270 && rect.right < 700
							&& rect.bottom < 900) {
						bitmap = mSpenSurfaceView.captureCurrentView(true);

						int size;
						if ((int) (rect.bottom - rect.top) > (int) (rect.right - rect.left))
							size = (int) (rect.bottom - rect.top);
						else
							size = (int) (rect.right - rect.left);
						
						bitmap = process.createCroppedBitmap(bitmap,
								(int) rect.top, (int) rect.left, size, size);
						bitmap = process.getResizedBitmap(bitmap, 100, 100);
						images.add(0, bitmap);
						adapter.notifyDataSetChanged();
					}
				} else {
					Toast.makeText(mContext,
							"You can't add more than 6 materials in each time",
							Toast.LENGTH_SHORT).show();
				}
			}
		}
	};

	private OnTouchListener imgPenTouch = new OnTouchListener() {

		@Override
		public boolean onTouch(View v, MotionEvent event) {
			selectButton(v);
			if (mSpenSurfaceView.getToolTypeAction(SpenSurfaceView.TOOL_SPEN) != SpenSurfaceView.ACTION_STROKE) {
				mMode = MODE_PEN;
				mSpenSurfaceView.setToolTypeAction(SpenSurfaceView.TOOL_SPEN,
						SpenSurfaceView.ACTION_STROKE);
			}
			return false;
		}
	};

	private OnTouchListener imgTextTouch = new OnTouchListener() {

		@Override
		public boolean onTouch(View v, MotionEvent event) {
			if (mSpenSurfaceView.getToolTypeAction(SpenSurfaceView.TOOL_SPEN) == SpenSurfaceView.ACTION_TEXT) {

			} else {
				mMode = MODE_TEXT;
				selectButton(v);
				mSpenSurfaceView.setToolTypeAction(SpenSurfaceView.TOOL_SPEN,
						SpenSurfaceView.ACTION_TEXT);
			}
			return false;
		}
	};

	private OnTouchListener imgSelectTouch = new OnTouchListener() {

		@Override
		public boolean onTouch(View v, MotionEvent event) {
			selectButton(v);
			if (mSpenSurfaceView.getToolTypeAction(SpenSurfaceView.TOOL_SPEN) != SpenSurfaceView.ACTION_SELECTION) {
				mMode = MODE_SELECT;
				mSpenSurfaceView.setToolTypeAction(SpenSurfaceView.TOOL_SPEN,
						SpenSurfaceView.ACTION_SELECTION);
			}
			return false;
		}
	};

	private OnTouchListener imgViewTouch = new OnTouchListener() {

		@Override
		public boolean onTouch(View v, MotionEvent event) {
			selectButton(v);
			mSpenPageDoc.removeAllObject();
			mSpenSurfaceView.update();
			mSpenSurfaceView.setToolTypeAction(SpenSurfaceView.TOOL_SPEN,
					SpenSurfaceView.ACTION_NONE);
			MaterialViewTask task = new MaterialViewTask();
			task.execute();
			return false;
		}
	};

	private class MaterialViewTask extends AsyncTask<Void, Void, Void> {

		private ProgressDialog pd;

		@Override
		protected Void doInBackground(Void... params) {
			names = new ArrayList<SpenObjectTextBox>();
			for (int i = 0; i < images.size(); i++) {
				SpenObjectImage img = new SpenObjectImage();
				Bitmap bitmap = process.addBorder(images.get(i), 5);
				bitmap = process.getResizedBitmap(bitmap, 50, 50);
				img.setImage(bitmap);
				img.setRect(
						new RectF(250, 105 * i + 270, 350, 105 * i + 370),
						false);

				SpenObjectTextBox txtMaterialName = new SpenObjectTextBox();
				txtMaterialName.setText("Material Name");
				txtMaterialName.setRect(new RectF(400, 105 * i + 300, 600,
						105 * i + 340), false);
				txtMaterialName.setBackgroundColor(Color.YELLOW);
				txtMaterialName.setFontSize(20);
				txtMaterialName
						.setTextAlignment(SpenObjectTextBox.ALIGN_CENTER);
				mSpenPageDoc.appendObject(img);
				mSpenPageDoc.appendObject(txtMaterialName);
				names.add(txtMaterialName);
			}
			mSpenSurfaceView.update();
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			super.onPostExecute(result);
			pd.dismiss();
			galleryMaterials.setOnItemClickListener(new OnItemClickListener() {

				@Override
				public void onItemClick(AdapterView<?> parent, View v,
						int position, long id) {
					for (int i = 0; i < names.size(); i++) {
						names.get(i).setBackgroundColor(Color.YELLOW);
					}
					names.get(position).setBackgroundColor(Color.RED);
					mSpenSurfaceView.update();
				}
			});
		}

		@Override
		protected void onPreExecute() {
			pd = new ProgressDialog(AddMaterialActivity.this,
					R.style.MyDialogTheme);
			pd.setMessage("Exporting...");
			pd.show();
		}

	}

	private OnTouchListener imgSaveTouch = new OnTouchListener() {

		@Override
		public boolean onTouch(View v, MotionEvent event) {
			selectButton(v);
			ArrayList<Material> materials = new ArrayList<Material>();
			for (int i = 0; i < images.size(); i++) {
				Material m = new Material();
				m.setName(names.get(i).getText());
				m.setImage(images.get(i));
				materials.add(m);
			}

			MaterialControl control = new MaterialControl();
			DHDatabaseHelper helper = new DHDatabaseHelper(mContext);
			SQLiteDatabase wdb = helper.getWritableDatabase();
			control.addMaterial(materials, wdb);
			Toast.makeText(mContext, "Add Successfully", Toast.LENGTH_SHORT)
					.show();
			finish();
			return false;
		}
	};

	private void selectButton(View v) {
		imgPen.setSelected(false);
		imgSelect.setSelected(false);
		imgView.setSelected(false);
		imgSave.setSelected(false);

		v.setSelected(true);
	}

	private SpenControlListener mControlListener = new SpenControlListener() {

		@Override
		public void onRotationChanged(float arg0, SpenObjectBase arg1) {
		}

		@Override
		public void onRectChanged(RectF arg0, SpenObjectBase arg1) {
		}

		@Override
		public void onObjectChanged(ArrayList<SpenObjectBase> arg0) {
		}

		@Override
		public boolean onMenuSelected(ArrayList<SpenObjectBase> objectList,
				int itemId) {
			switch (itemId) {
			case CONTEXT_MENU_GALLERY:
				loadFromGallery();
				break;
			case CONTEXT_MENU_CAMERA:
				captureImage();
				break;
			}

			return true;
		}

		@Override
		public boolean onCreated(ArrayList<SpenObjectBase> objectList,
				ArrayList<Rect> relativeRectList,
				ArrayList<SpenContextMenuItemInfo> menu,
				ArrayList<Integer> styleList, int pressType, PointF point) {
			if (objectList.get(0).equals(imgMaterials)) {
				menu.add(new SpenContextMenuItemInfo(CONTEXT_MENU_GALLERY,
						"Load Photo", true));
				menu.add(new SpenContextMenuItemInfo(CONTEXT_MENU_CAMERA,
						"Take Photo", true));
			}

			return true;
		}

		@Override
		public boolean onClosed(ArrayList<SpenObjectBase> arg0) {
			return false;
		}
	};

	private void loadFromGallery() {
		try {
			Intent galleryIntent = new Intent(Intent.ACTION_GET_CONTENT);
			galleryIntent.setType("image/*");
			startActivityForResult(galleryIntent, REQUEST_CODE_IMAGE_GALLERY);
		} catch (ActivityNotFoundException e) {
			Toast.makeText(mContext, "Cannot find gallery.", Toast.LENGTH_SHORT)
					.show();
			e.printStackTrace();
			finish();
		}
	}

	private void captureImage() {
		CameraProcess process = new CameraProcess();
		if (process.isDeviceSupportCamera(mContext)) {
			Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
			startActivityForResult(intent, REQUEST_CODE_CAMERA_CAPTURE);
		} else
			Toast.makeText(mContext, "Cannot find camera.", Toast.LENGTH_SHORT)
					.show();
	}

	private void performCrop() {
		try {
			Intent cropIntent = new Intent("com.android.camera.action.CROP");
			cropIntent.setDataAndType(picUri, "image/*");
			cropIntent.putExtra("crop", "true");
			cropIntent.putExtra("aspectX", 600);
			cropIntent.putExtra("aspectY", 630);
			cropIntent.putExtra("outputX", 600);
			cropIntent.putExtra("outputY", 630);
			cropIntent.putExtra("scale", true);
			cropIntent.putExtra("return-data", true);

			File f = new File(Environment.getExternalStorageDirectory(),
					"/temporary_holder.jpg");
			try {
				f.createNewFile();
			} catch (IOException ex) {
				Log.e("io", ex.getMessage());
				finish();
			}

			Uri uri = Uri.fromFile(f);

			cropIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);

			startActivityForResult(cropIntent, REQUEST_CODE_CROP);
		} catch (ActivityNotFoundException anfe) {
			String errorMessage = "Whoops - your device doesn't support the crop action!";
			Toast toast = Toast.makeText(mContext, errorMessage,
					Toast.LENGTH_SHORT);
			toast.show();
			finish();
		}
	}

	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (resultCode == RESULT_OK) {
			if (data == null) {
				Toast.makeText(mContext, "Cannot find the image",
						Toast.LENGTH_SHORT).show();
				return;
			}

			if (requestCode == REQUEST_CODE_CAMERA_CAPTURE) {
				picUri = data.getData();
				performCrop();
			}

			if (requestCode == REQUEST_CODE_IMAGE_GALLERY) {
				picUri = data.getData();
				performCrop();
			}

			if (requestCode == REQUEST_CODE_CROP) {
				String filePath = Environment.getExternalStorageDirectory()
						+ "/temporary_holder.jpg";

				Bitmap thePic = BitmapFactory.decodeFile(filePath);
				imgMaterials.setImage(thePic);
				mSpenSurfaceView.update();
				thePic.recycle();
				thePic = null;
			}
		}
	}

	private void clearObject() {
		if (mSpenSurfaceView != null) {
			mSpenSurfaceView.close();
			mSpenSurfaceView = null;
		}

		if (mSpenNoteDoc != null) {
			try {
				mSpenNoteDoc.close();
			} catch (Exception i) {
				Log.d("Spen", i.getMessage());
				finish();
			}

			mSpenNoteDoc = null;
		}
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		clearObject();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.add_material, menu);
		return true;
	}

}
